//
// Composite.as - Base class for composite or piecewise curves.
//
// copyright (c) 2006-2007, Jim Armstrong.  All Rights Reserved.
//
// This software program is supplied 'as is' without any warranty, express, implied, 
// or otherwise, including without limitation all warranties of merchantability or fitness
// for a particular purpose.  Jim Armstrong shall not be liable for any special incidental, or 
// consequential damages, including, without limitation, lost revenues, lost profits, or 
// loss of prospective economic advantage, resulting from the use or misuse of this software 
// program.
//
// Programmed by:  Jim Armstrong, Singularity (www.algorithmist.net)
//

package singularity.geom;

  import flash.events.EventDispatcher;
  import flash.display.Graphics;
  import flash.display.Shape;
  import flash.geom.ColorTransform;

  import singularity.events.SingularityEvent;
  
  import singularity.numeric.Consts;
  import singularity.numeric.Gauss;
  import singularity.geom.FastCubicSpline;
  
  class Composite extends EventDispatcher {
    // core
    
    public var color(null, setColor) : Int;
    public var container(null, setContainer) : Shape;
    public var parameterize(null, setParameterize) : String;
    public var thickness(null, setThickness) : Int;
    // core
    var __count:Int;                  // count Float of points added
    var __invalidate:Bool;          // true if current coefficients are invalid
    var __error:SingularityEvent;      // reference to standard Error event
    var __container:Shape;             // reference to Shape in which curve is drawn
    var __consts:Consts;               // reference to commonly used constants

    // drawing
    var __color:Int;                // arc color
    var __thickness:Float;            // arc thickness
    
    // Arc-length computation and parameterization
    var __param:String;                // parameterization method
    var __integral:Gauss;              // Gauss-Legendre integration class
    var __arcLength:Float;            // current arc length
    var __spline:FastCubicSpline;      // interpolate arc-length vs. t

/**
* @description 	Method: Composite() - Construct a new base composite curve
*
* @return Nothing
*
* @since 1.0
*
*/
    public function new()
    {
		super();
		__color      = 0x0000ff;
		__thickness  = 1;
		__count      = 0;
		__invalidate = true;
		__container  = null;
		__arcLength  = -1;

		__error           = new SingularityEvent(SingularityEvent.ERROR);
		__error.classname = "Composite";

		__consts = new Consts();
		__spline = new FastCubicSpline();

		__integral = new Gauss();
    }
    
    public function setColor(_c:Int):Int{
      __color = _c;
    	return _c;
     }

    public function setThickness(_t:Int):Int{
      __thickness = Math.round(_t);
    	return _t;
     }
    
    public function setContainer(_s:Shape):Shape{
      __container = _s;
    	return _s;
     }
    
    public function setParameterize(_s:String):String{
      if( _s == Consts.ARC_LENGTH || _s == Consts.UNIFORM )
      {
        __param      = _s;
        __invalidate = true;
      }
    	return _s;
     }
    
    public function reColor(_c:Int):Void
    {
      var g:Graphics = __container.graphics;
      
      var colorXForm:ColorTransform = __container.transform.colorTransform;
      colorXForm.color = _c;
      __container.transform.colorTransform = colorXForm;
    }

    public function reDraw():Void
    {
      var g:Graphics = __container.graphics;
      
      var colorXForm:ColorTransform = __container.transform.colorTransform;
      colorXForm.color = __color;
      __container.transform.colorTransform = colorXForm;
    }

    // Following methods should be overridden in subclass    
    public function __integrand(_t:Float):Float { 
		throw("Composite::__integrand() must be overriden"); 
		return 0;
	}
    
    public function arcLength():Float { throw("Composite::arcLength() must be overriden"); 
	return 0;}
    
    public function arcLengthAt(_t:Float):Float { throw("Composite::arcLengthAt() must be overriden"); 
	return 0;}
      
    public function addControlPoint( _xCoord:Float, _yCoord:Float ):Void {throw("Composite::addControlPoint() must be overriden");}
    
    public function moveControlPoint(_indx:Int, _newX:Float, _newY:Float):Void {throw("Composite::addControlPoint() must be overriden");}
    
    public function draw(?_t:Float=1.0):Void {throw("Composite::draw() must be overriden");}
  	
  	public function reset():Void {throw("Composite::reset() must be overriden");}
  	
    public function getX(_t:Float):Float { throw("Composite::getX() must be overriden");
	return 0;}

    public function getY(_t:Float):Float { throw("Composite::getY() must be overriden");
	return 0;}
    
  }
